package p29_ControllerAdvice之ResponseBodyAdvice;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@Configuration
class WebConfig {
    /**
     * @ControllerAdvice定义的增强，统一表示全局增强
     * 在消息解析器每次将对象转为字符串写入响应体之前，就会回调ResponseBodyAdvice的实现类的两个方法
     */
    @ControllerAdvice
    public static class MyControllerAdvice implements ResponseBodyAdvice<Object> {
        //为true表示需要执行beforeBodyWrite方法
        @Override
        public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
            if (returnType.getMethodAnnotation(ResponseBody.class) != null ||
                    AnnotationUtils.findAnnotation(returnType.getContainingClass(), ResponseBody.class) != null) {
                return true;
            }
            return false;
        }

        //返回值为最后写入响应体的对象转的字符串
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
            if (body instanceof R) {
                return body;
            }
            return new R(true, 200, body);
        }
    }
}